# gui/video_player.py - Video player component

import os

import PyQt5.QtCore
from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QPushButton,
                             QSlider, QLabel, QFileDialog, QStyle)
from PyQt5.QtMultimedia import QMediaContent
from PyQt5.QtMultimediaWidgets import QVideoWidget
from PyQt5.QtMultimedia import QMediaPlayer
from PyQt5.QtCore import Qt, QUrl, pyqtSlot, QTimer


class VideoPlayer(QWidget):
    def __init__(self):
        super().__init__()

        # Create media player and video widget
        self.media_player = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.video_widget = QVideoWidget()

        # Set up the player
        self.media_player.setVideoOutput(self.video_widget)
        self.media_player.stateChanged.connect(self.media_state_changed)
        self.media_player.positionChanged.connect(self.position_changed)
        self.media_player.durationChanged.connect(self.duration_changed)
        self.media_player.error.connect(self.handle_error)

        # Set up the UI
        self._setup_ui()

        # Initialize timer for updating player position
        self.update_timer = QTimer(self)
        self.update_timer.setInterval(1000)  # Update every second
        self.update_timer.timeout.connect(self.update_ui)

    def _setup_ui(self):
        """Set up the video player UI components"""
        layout = QVBoxLayout()

        # Video display area
        layout.addWidget(self.video_widget)

        # Controls layout
        controls_layout = QHBoxLayout()

        # Play/Pause button
        self.play_button = QPushButton()
        self.play_button.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
        self.play_button.clicked.connect(self.play_pause)
        controls_layout.addWidget(self.play_button)

        # Stop button
        self.stop_button = QPushButton()
        self.stop_button.setIcon(self.style().standardIcon(QStyle.SP_MediaStop))
        self.stop_button.clicked.connect(self.stop)
        controls_layout.addWidget(self.stop_button)

        # Open file button
        self.open_button = QPushButton("Open Video")
        self.open_button.clicked.connect(self.open_file)
        controls_layout.addWidget(self.open_button)

        # Position slider
        self.position_slider = QSlider(Qt.Horizontal)
        self.position_slider.setRange(0, 0)
        self.position_slider.sliderMoved.connect(self.set_position)
        controls_layout.addWidget(self.position_slider)

        # Time display
        self.time_label = QLabel("00:00:00 / 00:00:00")
        controls_layout.addWidget(self.time_label)

        layout.addLayout(controls_layout)
        self.setLayout(layout)

    def open_file(self):
        """Open a video file from disk"""
        file_path, _ = QFileDialog.getOpenFileName(
            self, "Open Video", "", "Video Files (*.mp4 *.avi *.mkv *.mov)")

        if file_path:
            self.load_file(file_path)

    def load_file(self, file_path):
        """Load a video file into the player"""
        if not os.path.exists(file_path):
            return False

        self.media_player.setMedia(
            QMediaContent(QUrl.fromLocalFile(file_path)))
        self.play_button.setEnabled(True)
        self.stop_button.setEnabled(True)
        self.position_slider.setEnabled(True)

        # Auto-play the loaded video
        self.play()
        return True

    def play_pause(self):
        """Toggle between play and pause states"""
        if self.media_player.state() == QMediaPlayer.PlayingState:
            self.pause()
        else:
            self.play()

    def play(self):
        """Start playing the video"""
        self.media_player.play()
        self.play_button.setIcon(self.style().standardIcon(QStyle.SP_MediaPause))
        self.update_timer.start()

    def pause(self):
        """Pause the video"""
        self.media_player.pause()
        self.play_button.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
        self.update_timer.stop()

    def stop(self):
        """Stop the video playback"""
        self.media_player.stop()
        self.play_button.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
        self.update_timer.stop()

    @pyqtSlot(QMediaPlayer.State)
    def media_state_changed(self, state):
        """Handle media player state changes"""
        if state == QMediaPlayer.PlayingState:
            self.play_button.setIcon(self.style().standardIcon(QStyle.SP_MediaPause))
        else:
            self.play_button.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))

    @pyqtSlot('qint64')
    def position_changed(self, position):
        """Handle changes in the media position"""
        self.position_slider.setValue(position)

        # Update time label
        duration = self.media_player.duration()
        self.update_time_label(position, duration)

    @pyqtSlot('qint64')
    def duration_changed(self, duration):
        """Handle changes in the media duration"""
        self.position_slider.setRange(0, duration)

    @pyqtSlot(int)
    def set_position(self, position):
        """Set the media player position"""
        self.media_player.setPosition(position)

    def update_time_label(self, position, duration):
        """Update the time display label"""
        position_time = self.format_time(position)
        duration_time = self.format_time(duration)
        self.time_label.setText(f"{position_time} / {duration_time}")

    def format_time(self, milliseconds):
        """Format milliseconds as HH:MM:SS"""
        seconds = milliseconds // 1000
        hours = seconds // 3600
        minutes = (seconds % 3600) // 60
        seconds = seconds % 60
        return f"{hours:02d}:{minutes:02d}:{seconds:02d}"

    @pyqtSlot()
    def update_ui(self):
        """Update UI elements on timer tick"""
        position = self.media_player.position()
        duration = self.media_player.duration()
        self.update_time_label(position, duration)

    @pyqtSlot(QMediaPlayer.Error)
    def handle_error(self, error):
        """Handle media player errors"""
        # 从 error 枚举获取错误字符串
        error_string = self.get_error_string(error)

        self.play_button.setEnabled(False)
        self.stop_button.setEnabled(False)
        self.position_slider.setEnabled(False)
        self.time_label.setText(f"Error: {error_string}")

    def get_error_string(self, error):
        """将QMediaPlayer.Error转换为错误描述字符串"""
        error_strings = {
            QMediaPlayer.NoError: "No error",
            QMediaPlayer.ResourceError: "Resource error",
            QMediaPlayer.FormatError: "Format error",
            QMediaPlayer.NetworkError: "Network error",
            QMediaPlayer.AccessDeniedError: "Access denied",
            QMediaPlayer.ServiceMissingError: "Service missing"
        }
        return error_strings.get(error, f"Unknown error ({error})")

    def play_segment(self, start_time, end_time, file_path):
        """Play a specific segment of a video file"""
        if self.load_file(file_path):
            # Convert to milliseconds
            start_ms = int(start_time * 1000)

            # Set position and play
            self.media_player.setPosition(start_ms)
            self.play()

            # Schedule a stop at the end time
            duration = end_time - start_time
            QTimer.singleShot(int(duration * 1000), self.pause)
